Skip to content

Conversation

@metehanozdev
Copy link
Collaborator

why

what changed

test plan

tkattkat and others added 30 commits October 15, 2025 16:15
…1134)

- Add Locator.count() for CSS, text, and XPath selectors\n- Make text=
selector case-insensitive for both count() and resolveNode()\n- Add
tests for locator count (CSS, text, XPath, iframes, shadow DOM)

---------

Co-authored-by: Sean McGuire <seanmcguire1@outlook.com>
# why

# what changed

# test plan
# why

currently, we have no support for using combinations of keys in keypress
method

# what changed

added support for using key combinations 

# test plan

added test file to test added functionality + pre existing
# why

we need to upgrade from ai sdk v4 to v5

# what changed

migrated from v4 to v5

# test plan
# why

we are missing pageurl, and timestamp in all agent results, and the
playwright arguments from stagehand agent results

# what changed

added pageurl, and timestamp in all agent results, and the playwright
arguments to stagehand agent results

# test plan

tested locally
tkattkat and others added 30 commits December 29, 2025 18:21
## Why

The agent currently provides no indication when it stops due to reaching
the max step limit. Users see `success: false` and `completed: false`
but have no way to distinguish between a max steps stop vs other failure
scenarios.

Additionally, tool logs display arguments as stringified JSON which is
hard to read.

## What Changed

**Max steps indication:**
- Added INFO-level log: `Agent stopped: reached maximum steps (X)`
- Set the result `message` field to indicate the stop reason
- Only triggers when step count actually reaches `maxSteps` (not on
other incomplete executions)

**Tool logging cleanup:**
- Changed tool logs to use `type: "object"` 
- Removed verbose/redundant fields (coordinates, processed) from some
tool logs

## Test Plan

- [x] Run agent with a low `maxSteps` value (e.g., 2)
- [x] Verify log output shows: `Agent stopped: reached maximum steps
(2)`
- [x] Verify `result.message` contains the max steps indication
- [x] Verify `result.success` is `false` and `result.completed` is
`false`
- [x] Verify `result.actions` still contains all actions performed
before stopping
# why

- fixes an incorrect usage of defining a model in docs 
- adds docs for dragAndDrop, and hover 
- updates return type of click 

part of STG-1030
part of STG-1076
# what changed

updated docs 

# test plan



<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Corrected v3 docs to use modelName (not model) in Stagehand model
configuration examples for OpenAI and Anthropic, and expanded Page API
docs with new methods and updated return types. Addresses STG-1030 and
prevents misconfiguration by aligning examples with the current API.

- **New Features**
- Documented hover(), scroll(), and dragAndDrop() with returnXpath
behavior and examples.
- Clarified click() return type (now returns a string) and updated
examples.

<sup>Written for commit a2fa2c7.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
Updated all active documentation and code to point to Discord community instead of Slack. All community links now use https://stagehand.dev/discord for better SEO.

**Changes:**
- Replaced Slack badges with Discord in README files
- Updated community links in documentation pages and error messages
- Removed Slack footer link from docs config
- Excluded historical changelogs and changesets

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Switched all community references from Slack to Discord, updating badges, links, docs, and messages to point to https://stagehand.dev/discord for better SEO.

- **Refactors**
  - Replaced Slack badges with Discord (added dark/light Discord SVGs, removed Slack SVGs).
  - Updated README files, docs pages, and cards to use https://stagehand.dev/discord.
  - Updated example and SDK error messages to mention Discord.
  - Removed Slack footer link; docs anchors now point to https://stagehand.dev/discord.
  - Excluded historical changelogs and changesets.
  - Updated license badges to 32px height to match Discord badges.

<sup>Written for commit 75e632a. Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why
- this eval went stale (website changed) & was causing regression evals
to fail in CI
# what changed
- updated the eval to use a cloned site
- updated success condition to check for exact value, since we no longer
need to tolerate a range (we are now using a cloned site that wont
change)
- also updated formatting for an unrelated changeset
# test plan
- this is it
# why
- when cached act & agent runs fail and need to rerun inference (self
heal), the default model was getting used every time. it should have
been using the original model that was defined by the user.
# what changed
- added logic to pass the the resolved `LLMClient` from
`Stagehand.act()` & `Stagehand.agent()` into `ActCache.tryReplay` &
`AgentCache.tryReplay(AsStream)` so cache hits reuse the same client as
their original runs and only fall back to the default when no override
is provided
# test plan
- added unit tests which confirm that act & agent caches use the
provided override client and that non LLM steps (like goto) replay
successfully without requiring one

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes a bug where cache replay used the default model after an action
failed; agent and act replays now use the requested model when inference
is rerun. Addresses Linear STG-930.

- **Bug Fixes**
- Pass the resolved LLM client (from options.model) into ActCache and
AgentCache replay paths, including streaming.
- Use the effective client when re-executing act and fillForm steps
during replay.
- Keep normal cache hits unchanged; only reruns use the specified model.

<sup>Written for commit 615c997.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why

currently using custom tools requires importing from a separate package

# what changed

- exported tool function & type 
- added test for exported function and type

# test plan

wrote tests & tested locally 


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Exported the tool function and Tool type from Stagehand core so users
can define custom tools without installing an extra package. Added tests
to confirm the exports and usage.

<sup>Written for commit 752ee8d.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why
Right now our server `/end` endpoint doesn’t match the production
Stagehand API contract: prod expects a non-empty JSON body when
`Content-Type: application/json` is set, so a call to `/end` that sends
an empty body fails. This change makes our server + OpenAPI spec match
prod so downstream generated SDKs send an empty object.

# what changed
Defined a strict empty-object request schema for `/end`
(`SessionEndRequest`) and made it a required request body in the route +
emitted OpenAPI. Updated the /end handler response to match prod `({
"success": true })` and added a server test covering the body
requirement.

- Also added a `stainless.yaml`
# test plan
Regenerate the Python SDK and verify sessions.end() succeeds against
production
# why
Generated sdks need to send empty object for /end endpoint to match prod
api
# what changed
Added dummy optional param to schema to force proper code gen
# test plan
Confirmed that the generated wheel linked below by stainless is correct.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Added an optional _forceBody field to SessionEndRequest so Stainless
generates a body parameter for the endpoint. The server still accepts {}
and clients can omit the field, fixing missing-body issues on session
end requests.

<sup>Written for commit 7f8a7bc.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
## Summary
Ollama models now work with the AI SDK provider format (e.g.,
`ollama/qwen3:1.7b`). Previously, using ollama would fail with
`UnsupportedAISDKModelProviderError`. Closes #1164

## Changes
- Filter out undefined values when checking if `clientOptions` has
meaningful data in `getAISDKLanguageModel`
- Skip error logging for providers that intentionally don't require API
keys (like ollama)

## Testing
Tested with `model: "ollama/qwen3:1.7b"` and verified Stagehand
initializes successfully without errors.


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Enable Ollama models to work with the AI SDK provider format (e.g.,
ollama/qwen3:1.7b). Fixes initialization errors and removes unnecessary
API key warnings.

- **Bug Fixes**
- Treat clientOptions as present only when values are
non-null/non-undefined.
- Skip "unknown env var" logging for providers that don’t require API
keys (ollama).
- Use createOllama to support custom baseURL and cases where an apiKey
is provided.

<sup>Written for commit d3001d5.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
## Summary
Fix support for the "ControlOrMeta" modifier key in keyboard event handling. This key is sent by Google CUA when clearBeforeTyping is enabled for form filling. Without this normalization, users saw unexpected "type A, backspace, then fill" behavior.

## Test Plan
- Unit test verifies "ControlOrMeta" maps to "Meta" on Mac and "Control" on other platforms
- Browser test confirms ControlOrMeta+A correctly selects all text for replacement

🤖 Generated with Claude Code

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fix keyboard modifier normalization by mapping "ControlOrMeta" to Meta on macOS and Control on other platforms. This restores shortcuts like Cmd/Ctrl+A during Google CUA clear-before-typing form filling and prevents the "type A, backspace, then fill" behavior.

<sup>Written for commit f1106a9. Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why

currently there is a url check condition, which often causes apple_tv
and nbaTrades to fail.
the youtube eval also always fails due to the page not loadkng 

# what changed

- update evals with url checks to not use url checks, 
- remove youtube eval 

# test plan

ran the evals 

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Reduce flaky agent evals by simplifying success checks and using
screenshot-based evaluation with agent reasoning. Removed the broken
YouTube task and improved reliability across Apple TV, AllRecipes,
Google Maps, GitHub React version, and the arXiv GPT-4 report.

- **Bug Fixes**
- all_recipes, apple_tv, nba_trades: success now relies only on agent
evaluation; removed URL checks.
- iframe_form_multiple: updated instructions and switched to
screenshot-based evaluation using agent reasoning; single evaluator YES.
- github_react_version: switched to screenshot-based evaluation using
agent reasoning; single evaluator YES.
- google_maps and google_maps_2: switched to screenshot-based evaluation
using agent reasoning; simplified success to a single evaluator YES.
- arxiv_gpt_report: added screenshot-based evaluation with agent
reasoning; verifies the correct date answer ('03-27-2023'); single
evaluator YES.
- Removed YouTube eval and its config entry due to persistent page load
failures.

<sup>Written for commit bd1e96d.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
## Summary
- Documents the `BROWSERBASE_CONFIG_DIR` environment variable for file-based session logging
- Covers setup, usage, and log file types (`llm_events.log`, `cdp_events.log`, `stagehand.log`)
- Includes examples for real-time monitoring with `tail -f` and chronological review

<img width="559" height="549" alt="image" src="https://github.com/user-attachments/assets/0ddffca0-ef1c-4f78-978e-88c6c212918e" />

<img width="571" height="715" alt="image" src="https://github.com/user-attachments/assets/1d0370c9-a6a7-4d17-bddf-0d8cea05dfb8" />


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Document file-based Stagehand session logging via BROWSERBASE_CONFIG_DIR with setup, log paths, tail/review tips, and log file types. Also fix broken links in Next Steps and add missing leading slashes in observability.

<sup>Written for commit bb71828. Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# Why

Previously, agent executions could end without a structured final
response - either by hitting `maxSteps` or the LLM breaking out of its
loop without calling the `close` tool. This made it difficult to:
1. Reliably determine if a task was completed successfully
2. Extract structured data from the agent's execution

# What Changed

### Ensured Close Tool is Always Called
- Added `handleCloseToolCall` utility that forces a `close` tool call
via a separate `generateText` call when the main agent loop ends without
explicitly closing
- Integrated via new `ensureClosed` private method in
`v3AgentHandler.ts`
- Works for both `execute()` and `stream()` modes
- Triggers when `maxSteps` is reached or the LLM stops ( completes its
task)
### Added Output Schema Support (Experimental)
- Users can now pass a Zod schema to `agent.execute({ output:
z.object({...}) })` to return structured data at the end of execution
- The schema dynamically extends the close tool's input schema
- Extracted data is returned in `result.output`
- Added validation:
  - **CUA mode**: Throws `StagehandInvalidArgumentError` (not supported)
- **Non-CUA without `experimental: true`**: Throws
`ExperimentalNotConfiguredError`

### Example Usage
```typescript
const result = await agent.execute({
  instruction: "search for a shampoo on amazon and click into one of the results",
  maxSteps: 20,
  output: z.object({
    productName: z.string().describe("The name of the shampoo product"),
    price: z.string().describe("The price of the product"),
    rating: z.string().describe("The star rating of the product"),
  }),
});

console.log(result.output);
// { productName: "...", price: "$12.99", rating: "4.5 out of 5 stars" }
```

# Test Plan

- [x] Verify close tool is called when agent naturally completes (no
change in behavior)
- [x] Verify close tool is forced when `maxSteps` is reached
- [x] Verify `output` schema extracts data correctly in `execute()` mode
- [x] Verify `output` schema extracts data correctly in `stream()` mode
- [x] Verify `output` throws `StagehandInvalidArgumentError` when used
with CUA mode
- [x] Verify `output` throws `ExperimentalNotConfiguredError` when used
without `experimental: true`


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Ensures every agent run ends with a structured final response and adds
optional structured output via a Zod schema. Improves reliability by
always setting completion status and final reasoning.

- **New Features**
- Always triggers a "close" tool call at the end of a run (LLM stops or
maxSteps), for both execute() and stream().
- Optional output schema: pass output: z.object({...}) to return typed
data in result.output.
- Validation: output schema is not supported in CUA (throws
StagehandInvalidArgumentError). In non-CUA, requires experimental: true
(throws ExperimentalNotConfiguredError otherwise).
- Removed "close" from the main tool list and system prompt; closing is
handled automatically post-run.

<sup>Written for commit dfb703a.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Nick Sweeting <github@sweeting.me>
# why
- adds support for a new function: `page.waitForSelector()`, which works
with cross-iframe selectors & cross-shadow root selectors
# what changed
- added `page.waitForSelector()` which returns `true` when the element
that the selector points to resolves, and times out with an error when
it does not resolve
# test plan
- added a bunch of e2e test cases, covering various CSS selector types,
& cross iframe/shadow root cases
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds Page.waitForSelector() to wait for CSS or XPath targets to reach a
state, piercing shadow DOM and traversing iframes. This makes waits
reliable across complex trees and uses MutationObserver for efficiency.

- **New Features**
- Page.waitForSelector(selector, { state, timeout, pierceShadow }) with
states: attached, detached, visible, hidden (defaults: visible, 30s,
pierceShadow=true).
- Supports CSS and XPath (xpath= or /), including open and closed shadow
DOM via the V3 piercer.
- Works across iframes and with '>>' hop notation; resolves the correct
frame automatically.
  - Clear timeout errors; no polling (MutationObserver-based).

- **Refactors**
- Added resolveLocatorTarget to unify hop/XPath frame resolution and
reuse in waitForSelector.
  - Exported waitForSelector locator script under dom/locatorScripts.

<sup>Written for commit a238850.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: tkattkat <tkat@tkat.net>
# why
- to expose a public API for the snapshotting functionality used by
stagehand internally
# what changed
- added a new `page.snapshot()` function, which returns a
`SnapshotResult` object containing:
- a stringified, hierarchical tree representation of the DOM (the same
one that is given to the LLM internally)
- an xpath map, which contains a mapping of xpaths for elements on the
page, keyed by IDs
- a URL map, which contains a mapping of all URLs inlcuded in the page,
keyed by IDs
# test plan
- we already have comprehensive testing for the internals of this
function (`captureHybridSnapshot()`), and this new function does not
have any additional branching logic. existing unit tests & evals should
suffice.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Exposes a public page.snapshot() API to capture a formatted DOM snapshot
with xpath and URL maps. Addresses STG-1082 by making the internal
snapshotter available to users.

- New Features
- Added page.snapshot(): returns SnapshotResult { formattedTree,
xpathMap, urlMap } using captureHybridSnapshot (pierces shadow DOM).
- Introduced StagehandSnapshotError for snapshot failures (keeps
original cause).
  - Exported SnapshotResult type.

- Refactors
- StagehandError now accepts and stores an optional cause for better
error chaining.

<sup>Written for commit e89840f.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why
When trying to run the server binary, was seeing `Error: ENOENT: no such
file or directory, open
'C:\Users\Administrator\Desktop\python\stagehand-python-stainless\bin\sea\static\logo.svg'`
# what changed
Only registering swagger docs when NODE_ENV is `developement`
# test plan
Will confirm that this resolves the error

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Disable Swagger UI in production by registering it only when NODE_ENV is
"development". This prevents SEA binary runtime errors caused by missing
static assets (e.g., logo.svg).

<sup>Written for commit 46282a2.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why
Once [this PR](browserbase/stagehand-python#264)
is merged into core, we no longer need to send `x-language` and
`x-sdk-version` headers in our generated SDKs, since they send the
`x-stainless` equivalents automatically.
# what changed
Thus, this PR removes these from the openapi spec, so that the generated
clients will stop having these fields.
# test plan
Will ensure that new generated sdks work successfully.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Removed x-language and x-sdk-version headers from the OpenAPI spec and
server types, since generated SDKs now send x-stainless headers
automatically. This simplifies SDK generation and removes redundant
headers.

- **Migration**
- Regenerate SDKs after the core change that adds x-stainless headers is
merged.
- Stop sending x-language and x-sdk-version in clients; rely on
x-stainless headers.

<sup>Written for commit df65fe9.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
…#1526)

# why

`https://stagehand.stldocs.app/api/python/resources/sessions/methods/start`
examples were showing `model_name="gpt-4o"`.
# what changed
Changed zod schemas so that the examples show the `provider/model`
syntax
# test plan


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Updated Zod schemas and OpenAPI examples to use provider/model syntax
for modelName (e.g., "openai/gpt-4o"). This aligns the docs with the API
and fixes incorrect examples shown in the Session start endpoint.

<sup>Written for commit 5657c1e.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why

we need to update the docs to show new languages 

# what changed

# test plan

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds multi-language SDK docs with a sidebar language selector and synced
code block languages, covering TypeScript, Python, Java, Go, and Ruby.
Adds the canonical OpenAPI spec and auto-syncs SDK pages from GitHub
READMEs.

- **New Features**
  - Added language selector that syncs with code blocks across pages.
  - Updated navigation to language dropdowns for v3.
  - Linked docs to the canonical OpenAPI spec.
  - Added sync script to generate SDK MDX from GitHub READMEs.
  - Added SDK pages for Go, Java, Python, and Ruby.
- Added migration guide for Python v2→v3 and updated the TypeScript
migration page.

- **Migration**
- To refresh SDK docs, run: node packages/docs/scripts/sync-sdk-docs.js.

<sup>Written for commit 833eb27.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
# why
Launch day!
# what changed

# test plan


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Bump @browserbasehq/stagehand-server version from 3.3.0 to 3.4.0 to
publish the new release. No code or runtime changes.

<sup>Written for commit 24b5aff.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
# why

sdk docs are out of date
we need a call out that points to the python migration guide 

# what changed

sync docs to latest versions of readme 
added call out pointing to python migration guide 
# test plan

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Synced SDK docs for Go, Java, Python, and Ruby to the latest content and
added a Python v2→v3 migration callout. Updates simplify examples,
remove deprecated headers, and bump install versions for a smoother
onboarding.

- **New Features**
- Added a Python migration callout and expanded docs with local mode,
streaming/SSE, logging, client config, error handling, retries/timeouts,
raw responses, and strict validation.

- **Refactors**
  - Updated install snippets: Go v0.17.1, Java 0.6.1, Ruby 0.6.2.
- Removed XLanguage/XSDKVersion headers and frameId requirements from
examples; refreshed intros with “What is Stagehand?” and “Why
Stagehand?”.

<sup>Written for commit 4501246.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
## Summary
Added comprehensive documentation for the `excludeTools` feature in the stagehand agent. This parameter allows developers to restrict which tools the agent can use during execution.

## Changes
- Added "Exclude Tools" section to basics/agent.mdx with usage examples and available tools by mode
- Updated Feature Availability table to show excludeTools support
- Added ParamField documentation to API references for both AgentExecuteOptions and AgentStreamExecuteOptions
- Included practical use case examples demonstrating common tool exclusion patterns

The feature is only available in non-CUA modes and requires `experimental: true` in the Stagehand constructor.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Add documentation for the excludeTools option in the Stagehand agent to let developers block specific tools per execution. Includes basic usage, available tools by mode (DOM/Hybrid), API reference entries for AgentExecuteOptions and AgentStreamExecuteOptions, a Feature Availability table update, and a note that the feature is experimental and non-CUA only.

<sup>Written for commit 9a326f9. Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
)

# why
Log with the url mappings is confusing, makes it seem as if the url was
not properly extracted.

# what changed
Move the extraction completion log to after the URL injection step, so
the log reflects the state of the response after URLs have been properly
injected into the output.

# test plan

Co-authored-by: Chromie Bot <chromie@browserbase.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Chromie <miguel@browserbase.com>
Co-authored-by: Chromie Bot <chromie@browserbase.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
…gString fix (#1553)

# why
Fixes for having openapi spec pass stainless checks.
# what changed

# test plan
Fixes two issues with the docs language dropdown:

1. **Icon confusion**: Changed all language dropdown icons to a generic
`code` icon instead of language-specific logos (e.g., Python logo
showing for every non-TypeScript option).
2. **Navigation sync**: Clicking a language in the dropdown now
navigates to the correct SDK page (e.g., selecting Go goes to
`/v3/sdk/go`).

Also optimized performance by replacing all `setTimeout` calls with
`requestAnimationFrame` for immediate, frame-synced updates and removed
redundant duplicate function calls.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the docs language dropdown to use a generic code icon and ensures
selecting a language navigates to the right docs page.

- **Bug Fixes**
  - Set all dropdown icons to "code" in docs.json.
- Selecting a language now routes to its docs page (e.g., Go →
/v3/sdk/go) and correctly handles trailing slashes.

- **Refactors**
- Replaced setTimeout with requestAnimationFrame (onNextFrame) and
MutationObserver for menu selection.
  - Removed duplicate delayed calls and initialized immediately.
- Debounced DOM updates via rAF in observers and kept code block
language in sync.

<sup>Written for commit a4ba7b8.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
## Summary
- Change CustomOpenAIClient response format from json_schema to
json_object for broader compatibility with models like ZhiPu
- Add prompt-based JSON schema instructions for models without native
structured output support
- Export CustomOpenAIClient from public types for easier developer
access

```
import { Stagehand, CustomOpenAIClient } from "@browserbasehq/stagehand";
import OpenAI from "openai";

const stagehand = new Stagehand({
  env: "BROWSERBASE",
  disableAPI: true,
  llmClient: new CustomOpenAIClient({
    modelName: "glm-4.6v",
    client: new OpenAI({
      apiKey: "your-zhipu-key",
      baseURL: "https://open.bigmodel.cn/api/paas/v4",
    }),
  }),
});
```

## Testing
Verified with ZhiPu glm-4.6v model using Browserbase integration with
successful extract, act, and observe operations.

Closes #1510

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Added support for ZhiPu models by switching CustomOpenAIClient to
json_object responses and adding a schema-instruction prompt for
structured JSON. Also exported CustomOpenAIClient from public types for
easier use.

- **Bug Fixes**
- Use shared validateZodSchema for field-level errors, add
request-scoped logging, handle invalid JSON with retries, and throw
CreateChatCompletionResponseError with the specific message.

<sup>Written for commit 8267c0d.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
# why

the dropdown in the docs was having weird behavior where regardless of
the language you choose, you'll always be routed to the python sdk.

# what changed

removing other pages from dropdown to prevent autorouting to python. 

old: 


https://github.com/user-attachments/assets/49618655-6c2d-477f-b573-a3ca1f7ca555

new: 


https://github.com/user-attachments/assets/635ca14b-ffa2-47f6-b474-709bb0269175

# test plan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.